﻿/***********************************************
Name：全局管理器
Desc：封装资源管理器、场景管理器，由游戏世界调用
Auth：Cool.Cat@2013-03-15
***********************************************/
#pragma once
#include "SIX_MusicMgr.h"
#include "SIX_FileSystem.h"
#include "SIX_Proxy.h"
#include "SIX_Logger.h"
#include <SIX_XMLParser.h>
#include "SIX_DSTPL.h"
#include "SIX_SystemInfo.h"
#include "SIX_TMap.h"
#include "SIX_TalkingGame.h"
#include "SIX_DelayLoadMgr.h"

USING_NS_CC;

class SIX_MusicMgr;
class SIX_FileSystem;
class SIX_Proxy;
class SIX_Logger;
class SIX_SystemInfo;
class SIX_TalkingGame;
class SIX_DelayLoadMgr;

typedef struct tagConfigInfo {
	string ip;
	unsigned int port;
	float debug_number1;
	float debug_number2;
	tagConfigInfo()
	{
		ip.clear();
		port = 0;
		debug_number1 = 0.0f;
		debug_number2 = 0.0f;
	}
} CONFIG_INFO;

typedef struct tagParamsInfo {
	tagParamsInfo()
	{
		name = "";
		intValue = 0;
		floatValue = 0.0f;
	}

	void setName(string v){name=v;};
	string getName(){return name;}

	void setIntValue(int v){intValue=v;}
	int getIntValue(){return intValue;}

	void setFloatValue(float v){floatValue=v;}
	float getFloatValue(){return floatValue;}
private:
	string name;
	int intValue;
	float floatValue;
}PARAMS_INFO;

class SIX_GlobalMgr:public TSingleton<SIX_GlobalMgr> {
public:
	SIX_GlobalMgr()
	{
		m_bInited = false;
		setResourceKey();
		m_LastBackgroundMusicIdx = 0;
		SetLastLoginName();
		SetLastLoginPass();

		pMusicMgr = 0;
		pProxy = 0;
		pFS = 0;
		pSysInfo = 0;
		pLogger = 0;
		pStats = 0;
		pDelayLoadMgr = 0;

		pConfig = 0;
	}
	~SIX_GlobalMgr()
	{
		WLOG("~SIX_GlobalMgr.Done");

		CC_SAFE_DELETE(pMusicMgr);
		CC_SAFE_DELETE(pProxy);
		CC_SAFE_DELETE(pFS);
		CC_SAFE_DELETE(pSysInfo);
		CC_SAFE_DELETE(pLogger);
		CC_SAFE_DELETE(pStats);
		CC_SAFE_DELETE(pDelayLoadMgr);
	}
	void UnInitialization(bool bNeedDelete=true)
	{
		// 卸载脚本引擎
		CCScriptEngineManager::purgeSharedManager();
		// 终结引擎主循环
		CCDirector::sharedDirector()->end();

		// 如果没释放过，那么这里做个标记，等SIX_UIScene析构时再释放之~
		// 从而保证SIX_GlobalMgr只自释放一次。
		// Cool.Cat
		if (bNeedDelete && !m_bAlreadyDeleted)
		{
			WLOG("UnInitialization");
			m_bAlreadyDeleted = true;
		}
	}
	// ResourceKey		资源文件解密密钥
	// ResourcePath		资源目录
	// ConfigFile		配置文件
	// LogFileName		日志文件
	void Initialization(char *ResourcePath="",char *ConfigFile="",char *ResourceKey="",char *LogFileName="")
	{
		if (m_bInited)
			return;

		m_bInited = true;
		setResourceKey(ResourceKey);
 
		m_LastBackgroundMusicIdx = 0;

		pLogger = new SIX_Logger();
		pLogger->SetLogName(LogFileName);
		pLogger->setDecryptKey(ResourceKey);
		pMusicMgr = SIX_MusicMgr::GetInstance();
		//pProxy = SIX_Proxy::GetInstance();
		pFS = SIX_FileSystem::GetInstance();
		pSysInfo = SIX_SystemInfo::GetInstance();
		pStats = SIX_TalkingGame::GetInstance();
		//pDelayLoadMgr = SIX_DelayLoadMgr::GetInstance();
		// 开启TalkingGame日志（发布正式版时这里要注释掉）
		// Cool.Cat
		pStats->setVerboseLogEnabled();
        
		WLOG("Initialization");

		// 解压并解密资源文件
		// Cool.Cat
		this->UnZipAndDecryptFile();
		// 读取个人配置
		this->LoadProfile();
		// 加载配置文件
		//if (ResourcePath && strlen(ResourcePath) && ConfigFile && strlen(ConfigFile))
        this->ReloadConfigFile(ResourcePath,ConfigFile);
	}

    void runProxy()
    {
        pProxy = SIX_Proxy::GetInstance();
        pDelayLoadMgr = SIX_DelayLoadMgr::GetInstance();
    }
    
	void setResourceKey(char *ResourceKey="")
	{
        if (!ResourceKey)
			return;
		m_sResourceKey.clear();
		m_sResourceKey.append(ResourceKey);
		// 设置资源解密密钥
		CCFileUtils::sharedFileUtils()->setDecryptKey(this->getResourceKey().c_str());
        CocosDenshion::SimpleAudioEngine::sharedEngine()->setResourceKey((char*)this->getResourceKey().c_str());
	}

	string &getResourceKey()
	{
		return m_sResourceKey;
	}

	void UnZipAndDecryptFile();

	// 玩家信息本地存储
	void LoadProfile(char *ProPath="Prof");
	void SaveProfile(char *ProPath="Prof");
	bool getProData(const string &strNodeName, const string &strAttributeName, string &strValue);
	void setProData(const string &strNodeName, const string &strAttributeName, const string &strValue);

	void LoadMusic(const char *folder,const char *fName);
	void StopAllMusicAndEffect();
	void PlayNextBackgroundMusic();
	void PlayChangeSceneMusic();

	void ReloadConfigFile(char *resFolder,char *configFile)
	{
		if (!m_bInited)
			return;

		CC_SAFE_DELETE(pConfig);
		pConfig = new CONFIG_INFO();

		CCFileUtils::sharedFileUtils()->setResourceDirectory(resFolder);
		const char *pPath = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(configFile);
		SIXLog("pPath[%s]",pPath);
//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
		unsigned long len = 0;
		unsigned char *pData = CCFileUtils::sharedFileUtils()->getFileData(pPath, "rb", &len);
		if (!pData || !len)
		{
			CC_SAFE_DELETE(pData);
			SIXLog("GetConfigFile.C.Error");
			return;
		}

		SIX_XMLParser *pXML = new SIX_XMLParser();
		int retv = pXML->LoadXMLFromMemory(pData,len);
		if (retv!=0)
		{
			CC_SAFE_DELETE(pXML);
			CC_SAFE_DELETE(pData);
			SIXLog("GetConfigFile.D.Error");
			return;
		}

		this->ParseXML(pXML->GetXMLDataSet());

		CC_SAFE_DELETE(pData);

		SIX_XmlDataSet *pDataSet = 0;

		CCARRAY_FOREACH_T(pXML->GetXMLDataSet()->GetChildren(),pDataSet,SIX_XmlDataSet*)
		{
			// 跳过Root和Comment
			if (STRCMP(pDataSet->getKey().c_str(),"Element"))
				continue;

			if (pDataSet->pDataElement)
			{
				if (!STRCMP(pDataSet->getValue().c_str(),"address"))
				{
					SIX_KV *pKV = 0;
					CCARRAY_FOREACH_T(pDataSet->pDataElement->GetChildren(),pKV,SIX_KV*)
					{
						if (!STRCMP(pKV->getKey().c_str(),"ip"))
						{
							pConfig->ip.clear();
							pConfig->ip.append(pKV->getValue().c_str());
						}
						else if (!STRCMP(pKV->getKey().c_str(),"port"))
						{
							pConfig->port = (atoi)(pKV->getValue().c_str());
						}
					}
				}
				else if (!STRCMP(pDataSet->getValue().c_str(),"debug_number"))
				{
					SIX_KV *pKV = 0;
					CCARRAY_FOREACH_T(pDataSet->pDataElement->GetChildren(),pKV,SIX_KV*)
					{
						if (!STRCMP(pKV->getKey().c_str(),"number1"))
						{
							pConfig->debug_number1 = (atof)(pKV->getValue().c_str());
						}
						else if (!STRCMP(pKV->getKey().c_str(),"number2"))
						{
							pConfig->debug_number2 = (atof)(pKV->getValue().c_str());
						}
					}
				}
				// 牌动画参数控制/倒计时参数控制/结算时间参数控制
				else if (!STRCMP(pDataSet->getValue().c_str(),"AnimationParams") ||
					!STRCMP(pDataSet->getValue().c_str(),"CountDownParams") ||
					!STRCMP(pDataSet->getValue().c_str(),"SettleAccountsParams")
						)
				{
					SIX_XmlDataSet *pDataSetParams = 0;

					CCARRAY_FOREACH_T(pDataSet->pNode->GetChildren(),pDataSetParams,SIX_XmlDataSet*)
					{
						// 跳过Root和Comment
						if (STRCMP(pDataSetParams->getKey().c_str(),"Element"))
							continue;

						if (pDataSetParams->pDataElement)
						{
							SIX_KV *pKV = 0;
							PARAMS_INFO *pParamsInfo = new PARAMS_INFO();
							CCARRAY_FOREACH_T(pDataSetParams->pDataElement->GetChildren(),pKV,SIX_KV*)
							{
								if (!STRCMP(pKV->getKey().c_str(),"name"))
								{
									pParamsInfo->setName(pKV->getValue().c_str());
								}
								else if (!STRCMP(pKV->getKey().c_str(),"floatValue"))
								{
									pParamsInfo->setFloatValue((atof)(pKV->getValue().c_str()));
								}
								else if (!STRCMP(pKV->getKey().c_str(),"intValue"))
								{
									pParamsInfo->setIntValue((atoi)(pKV->getValue().c_str()));
								}
							}
							pParamsList.Add(pParamsInfo->getName(),pParamsInfo);
							//SIXLog("[%s].name[%s].floatValue[%.2f].intValue[%d]",
							//	pDataSet->getValue().getCString(),pParamsInfo->getName().c_str(),pParamsInfo->getFloatValue(),pParamsInfo->getIntValue());
						}
					}
					//SIXLog("-----------------------------------------");
				}
			}
		}

		pXML->ReleaseXMLDataSet();
		CC_SAFE_DELETE(pXML);

		SIXLog("pConfig.ip[%s].port[%d].debug_number1[%.4f].debug_number2[%.4f]",
			pConfig->ip.c_str(),
			pConfig->port,
			pConfig->debug_number1,
			pConfig->debug_number2
		);
//#else
//
//		TiXmlDocument *pXmlDocument = new TiXmlDocument();
//		if (!pXmlDocument->LoadFile( pPath ))
//		{
//			CC_SAFE_DELETE_ARRAY(pPath);
//			return;
//		}
//		CC_SAFE_DELETE_ARRAY(pPath);
//		TiXmlElement *pRoot = pXmlDocument->RootElement();
//		if (NULL == pRoot)
//		{
//			assert( 0 );
//			return;
//		}
//
//		TiXmlNode *pAddress = pRoot->FirstChild( "address" );
//		if (NULL == pAddress)
//		{
//			assert( 0 );
//			return;
//		}
//
//		TiXmlAttribute *pAttribute = pAddress->ToElement()->FirstAttribute();
//		while ( pAttribute )
//		{
//			const char *pName = pAttribute->Name();
//			if (0 == STRCMP(pName, "ip")  &&  0<strlen( pAttribute->Value() ))
//			{
//				sprintf(pIP, "%s", pAttribute->Value());
//			}
//			else if (0 == STRCMP(pName, "port")  &&  0<strlen( pAttribute->Value() ))
//			{
//				nPort = atoi( pAttribute->Value() );
//			}
//			pAttribute = pAttribute->Next();
//		}
//		pXmlDocument->Clear();
//		CC_SAFE_DELETE( pXmlDocument );
//#endif
	}
private:
	void ParseXML(SIX_DSTPL<SIX_XmlDataSet> *pXmlDataSet);
public:
	SIX_MusicMgr *GetMusicMgr() const {return &(*pMusicMgr);}
	SIX_Proxy *GetProxy() const {return &(*pProxy);}
	SIX_FileSystem *GetFS() const {return &(*pFS);}
	SIX_Logger *GetLogger() const {return &(*pLogger);}
	SIX_SystemInfo *GetSystemInfo() const {return &(*pSysInfo);}
	SIX_TalkingGame *GetStats() const {return &(*pStats);}
	SIX_DelayLoadMgr *GetDelayLoadMgr() const {return &(*pDelayLoadMgr);}
	CONFIG_INFO *GetConfig() const {return &(*pConfig);}
	bool IsAlreadyDeleted(){return m_bAlreadyDeleted;}

	float GetParamsFloatValue(string name)
	{
		PARAMS_INFO *pParamsInfo = pParamsList.Get(name);
		if (!pParamsInfo)
			return 0;
		return pParamsInfo->getFloatValue();
	}

	int GetParamsIntValue(string name)
	{
		PARAMS_INFO *pParamsInfo = pParamsList.Get(name);
		if (!pParamsInfo)
			return 0;
		return pParamsInfo->getIntValue();
	}

	char *GetLastLoginName(){return m_pLastLoginName;}
	void SetLastLoginName(const char *LastLoginName=""){memcpy(m_pLastLoginName,LastLoginName,strlen(LastLoginName));m_pLastLoginName[strlen(LastLoginName)]=0;}

	char *GetLastLoginPass(){return m_pLastLoginPass;}
	void SetLastLoginPass(const char *LastLoginPass=""){memcpy(m_pLastLoginPass,LastLoginPass,strlen(LastLoginPass));m_pLastLoginPass[strlen(LastLoginPass)]=0;}
private:
	// 音效管理器
	SIX_MusicMgr *pMusicMgr;
	// 网络消息代理
	SIX_Proxy *pProxy;
	// 文件管理器
	SIX_FileSystem *pFS;
	// 日志
	SIX_Logger *pLogger;
	// 系统信息管理器
	SIX_SystemInfo *pSysInfo;
	// 数据统计
	SIX_TalkingGame *pStats;
	// 延迟加载管理器
	SIX_DelayLoadMgr *pDelayLoadMgr;
	static bool m_bAlreadyDeleted;

	bool m_bInited;
	string m_sResourceKey;

	int m_LastBackgroundMusicIdx;
	// 配置参数
	CONFIG_INFO *pConfig;

	// 控制参数
	SIX_TMap<string,PARAMS_INFO*> pParamsList;

	// 上一次登录账户名
	char m_pLastLoginName[33];
	// 上一次登录账户密码
	char m_pLastLoginPass[33];
	map<string, map<string, string> > m_mReadWriteData;
};